package com.zhz.common.tool.excel.resolver.impl;

import com.zhz.common.tool.excel.annotation.Sheet;
import com.zhz.common.tool.excel.exception.CreateExcelException;
import com.zhz.common.tool.excel.exception.ExcelExportException;
import com.zhz.common.tool.excel.exception.NotHasDataRunTimeException;
import com.zhz.common.tool.excel.resolver.ExcelAble;
import com.zhz.common.tool.excel.utils.ExcelExportUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhouhengzhe
 * @date 2023/4/5
 */
@Slf4j
@Data
@EqualsAndHashCode(callSuper = true)
public class SheetExcelResolver extends DefaultExcelResolver {


    public SheetExcelResolver(Class<?> group) {
        super(group);
    }

    public SheetExcelResolver() {
    }

    /**
     * 解析数据列表，讲数据和Sheet分离开，
     * 每个Sheet对应一个数据列表
     *
     * @param wb
     * @param dataList
     * @param objData
     * @return
     */
    public Map<HSSFSheet, List> sheetResolver(HSSFWorkbook wb, List<?> dataList, Object objData) {
        Map<HSSFSheet, List> res = new HashMap<>();// 结果集合
        // 遍历数据列表解析data中的Sheet注解，并获取名称和对应的data列表
        if (dataList == null || dataList.size() == 0) {
            //throw new NotHasDataRunTimeException("没有数据，无法导出Excel");
            return null;
        }
        Object data = dataList.get(0);
        Class clazz = data.getClass();
        Sheet sheetAnnotation = (Sheet) clazz.getAnnotation(Sheet.class);
        String sheetName = null;
        SheetAnnotationResolver<Sheet> sheetAnnotationResolver = new SheetAnnotationResolver();
        if (sheetAnnotation == null) {
            return null;
        } else {
            // 获取SheetName数据
            sheetName = (String) sheetAnnotationResolver.resolve(sheetAnnotation, objData);
        }
        HSSFSheet sheetParent = wb.createSheet(sheetName);
        String pwd = sheetAnnotation.password();
        if (pwd != null && !pwd.equals("")) {//加密码
            sheetParent.protectSheet(pwd);
        }
        res.put(sheetParent, dataList);
        Field[] fields = clazz.getDeclaredFields();
        int index = 0;
        for (Field field : fields) {// 遍历data里面的所有字段，判断 数据模型中是否有 其他列表
            if (Collection.class.isAssignableFrom(field.getType())) {//该字段是集合，需要检测是否被Sheet标记
                for (Object item : dataList) {// datas中的有多少条数据就有多少个sheet
                    Map<HSSFSheet, List> itemRes = null;// 结果集合
                    Method method;
                    List itmeData = null;
                    try {
                        ExcelExportUtil excelExportUtil = new ExcelExportUtil();
                        if (field.getType().equals("boolean")) {// 基本变量
                            method = clazz.getMethod(excelExportUtil.getBooleanPrefix(field.getName()));
                        } else {
                            method = clazz.getMethod("get" + excelExportUtil.getMethodName(field.getName()));
                        }
                        itmeData = (List) method.invoke(item);
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                    itemRes = sheetResolver(wb, itmeData, item);
                    if (itemRes != null) {
                        res.putAll(itemRes);
                    }

                }
            }
        }
        return res;
    }

    public void checkExcel(List<?> dataList) {
        if (dataList == null || dataList.size() == 0) {
            throw new NotHasDataRunTimeException("没有数据，无法导出Excel");
        }
        if (dataList.size() >= 10000) {
            log.warn("导出数据量过大，无法导出Excel,最大只能导出1w，如果需要再大，请用大数据导出,具体可以看BaseEasyExcelExport");
            throw new ExcelExportException("导出数据量过大，无法导出Excel,最大只能导出1w，如果需要再大，请用大数据导出");
        }
        Object obj = dataList.get(0);
        Class clazz = obj.getClass();
        if (!ExcelAble.class.isAssignableFrom(clazz)) {//没有继承ExcelAble或实现BaseExcelVO
            throw new ExcelExportException("derived type Exception: Excel export must implement ExcelAble or extends BaseExcelVO");
        }
        Sheet sheet = (Sheet) clazz.getAnnotation(Sheet.class);
        if (sheet == null) {
            throw new CreateExcelException("You cannot create Excel without defining Sheet");
        }
    }

    /**
     * @param clazz
     */
    public void checkExcel(Class<?> clazz) {

        Field[] fields = clazz.getFields();
        for (Field field :
                fields) {

        }

    }

}
